﻿namespace Aldart.WebSockets.Server
{
    using System;
    using System.Net.Sockets;

    /// <summary>
    /// Handles the handshake with a client, raising an event when it is complete.
    /// </summary>
    public class Handshake
    {
        /// <summary>
        /// Designates the size of the buffer used for processing handshakes.
        /// </summary>
        private const int BufferSize = 1024;

        /// <summary>
        /// Field containing the TcpClient on which this handshake operates.
        /// </summary>
        private TcpClient client;

        /// <summary>
        /// Buffer used for received handshake data.
        /// </summary>
        private byte[] buffer;

        /// <summary>
        /// Initializes a new instance of the Handshake class.
        /// </summary>
        /// <param name="client">The client used for the handshake.</param>
        public Handshake(TcpClient client) {
            this.client = client;
            this.buffer = new byte[BufferSize];
        }

        /// <summary>
        /// Raised when the handshake is complete.
        /// </summary>
        public event EventHandler<HandshakeCompleteEventArgs> HandshakeComplete;

        /// <summary>
        /// Starts the handshake, which will be executed asynchronously, raising the HandshakeComplete event when it is done.
        /// </summary>
        public void Perform() {
            this.client.GetStream().BeginRead(this.buffer, 0, BufferSize, new AsyncCallback(this.DataRead), null);
        }

        /// <summary>
        /// Called when data for the handshake has been received from the client.
        /// </summary>
        /// <param name="result">Result object passed by the Framework</param>
        private void DataRead(IAsyncResult result) {
            // Read data from stream
            int bytesRead = this.client.GetStream().EndRead(result);
            Request request = new Request(this.buffer, 0, bytesRead, 8);

            // Construct response
            Request response = new Request();

            // Raise event
            if (this.HandshakeComplete != null) {
                this.HandshakeComplete(this, new HandshakeCompleteEventArgs { Client = this.client, Result = HandshakeResult.Success });
            }
        }
    }
}
